#include <stdio.h>
#include <string.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <fcntl.h>
#include "tools.h"
#include "md5.h"

// 根据文件路径获取文件的MD5值
uint8_t* getmd5_path(const char* path,uint8_t* encrypt)
{
	FILE* frp = fopen(path,"rb");
	if(NULL == frp)
	{
		perror("fopen");
		return NULL;
	}
	
	getmd5_file(frp,encrypt);
	fclose(frp);

	return encrypt;
}

// 根据文件描述符获取文件的MD5值
uint8_t* getmd5_fd(int fd,uint8_t* encrypt)
{
	FILE* frp = fdopen(fd,"rb");
	if(NULL == frp)
	{
		perror("fdopen");
		return NULL;
	}
	
	getmd5_file(frp,encrypt);
	fclose(frp);

	return encrypt;
}

// 根据文件指针获取文件的MD5值
uint8_t* getmd5_file(FILE* frp,uint8_t* encrypt)
{
	if(NULL == frp || NULL == encrypt)
	{
		printf("frp pointer or encrypt NULL\n");
		return NULL;
	}
	
	MD5_CTX md5;
	MD5Init(&md5);
	int ret = 0;
	uint8_t buf[1024] = {};
	
	rewind(frp);
	while(ret = fread(buf,1,sizeof(buf),frp))
	{
		MD5Update(&md5,buf,ret);
	}
	
	MD5Final(&md5,encrypt);
	
	return encrypt;
}

// 根据字符串获取MD5值
uint8_t* getmd5_str(char* str,uint8_t* encrypt)
{
	if(NULL == str || NULL == encrypt)
	{
		printf("str pointer or encrypt NULL\n");
		return NULL;
	}
	
	MD5_CTX md5;
	MD5Init(&md5);
	MD5Update(&md5,str,strlen(str));
	MD5Final(&md5,encrypt);
	
	return encrypt;
}

// 比较两个MD5值
int md5cmp(const uint8_t* enc1,const uint8_t* enc2)
{
	return strncmp(enc1,enc2,16);
}

// 显示MD5值
void show_md5(const uint8_t* encrypt)
{
	printf("md5:");
	for(int i=0; i<16; i++)
	{
		printf("%02x",encrypt[i]);	
	}
	printf("\n");
}


int main()
{
	FILE* frp = fopen("md5.h","rb");
	if(NULL == frp)
	{
		perror("fopen");
		return -1;
	}
	uint8_t md5[16] = {};
	show_md5(getmd5_file(frp,md5));
	show_md5(getmd5_str("zzxx",md5));
}
